/**
 * Created by XianTao on 2016/11/6
 * <p/>
 * Copyright (c) 2015-2015
 * Apache License
 * Version 2.0, January 2004
 * http://www.apache.org/licenses/
 */
package org.lego.wechat.base.service;

import org.lego.jpa.base.repository.BaseRepository;
import org.lego.jpa.base.service.BaseService;
import org.lego.jpa.base.util.DynamicSpecifications;
import org.lego.util.StringUtil;
import org.lego.wechat.base.api.MenuApi;
import org.lego.wechat.base.entity.WxMenu;
import org.lego.wechat.base.msg.menu.*;
import org.lego.wechat.base.repository.WxMenuRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class WxMenuService extends BaseService<WxMenu, String> {
    @Autowired
    private WxMenuRepository wxMenuRepository;
    @Autowired
    private MenuApi menuApi;

    @Override
    protected BaseRepository<WxMenu, String> getRepository() {
        return wxMenuRepository;
    }

    public Page<WxMenu> findByParentId(String parentId, PageRequest pageRequest) {
        Map<String, Object> searchParams = new HashMap<String, Object>();
        if (ObjectUtils.isEmpty(parentId)) {
            searchParams.put("ISNULL_parent.id", "null");
        } else {
            searchParams.put("EQ_parent.id", parentId);
        }
        return this.findAll(DynamicSpecifications.buildSpecification(searchParams, WxMenu.class), pageRequest);
    }

    /**
     * 将WxMenu转换为微信所需的Menu
     *
     * @return {@link org.lego.wechat.base.msg.menu.Menu}
     */
    public Menu generateMsgMenu(String corpId) {
        List<Button> buttonList = new ArrayList<Button>();

        Page<WxMenu> wxMenuPage = this.findByParentId(null, new PageRequest(0, WxMenu.MAX_MENU_NUMBER, Sort.Direction.ASC, "sort"));
        for (WxMenu wxMenu : wxMenuPage) {
            if (Menu.TYPE_CLICK.equals(wxMenu.getType())) {
                ClickButton clickButton = new ClickButton();
                clickButton.setName(wxMenu.getName());
                clickButton.setKey(wxMenu.getContent());
                buttonList.add(clickButton);
            } else if (Menu.TYPE_VIEW.equals(wxMenu.getType())) {
                ViewButton viewButton = new ViewButton();
                viewButton.setName(wxMenu.getName());
                viewButton.setUrl(wxMenu.getUrlByViewType(corpId));
                buttonList.add(viewButton);
            } else if (Menu.TYPE_COMPLEX.equals(wxMenu.getType())) {
                ComplexButton complexButton = new ComplexButton();
                complexButton.setName(wxMenu.getName());

                List<Button> subButtonList = new ArrayList<Button>();
                Page<WxMenu> subWxMenuList = this.findByParentId(wxMenu.getId(), new PageRequest(0, WxMenu.MAX_SUB_MENU_NUMBER, Sort.Direction.ASC, "sort"));
                for (WxMenu subWxMenu : subWxMenuList) {
                    if (Menu.TYPE_CLICK.equals(subWxMenu.getType())) {
                        ClickButton clickButton = new ClickButton();
                        clickButton.setName(subWxMenu.getName());
                        clickButton.setKey(subWxMenu.getContent());
                        subButtonList.add(clickButton);
                    } else if (Menu.TYPE_VIEW.equals(subWxMenu.getType())) {
                        ViewButton viewButton = new ViewButton();
                        viewButton.setName(subWxMenu.getName());
                        viewButton.setUrl(subWxMenu.getUrlByViewType(corpId));
                        subButtonList.add(viewButton);
                    } else {
                        throw new RuntimeException("unknown menu type: " + subWxMenu.getType());
                    }
                }
                complexButton.setSub_button(subButtonList.toArray(new Button[subButtonList.size()]));
                buttonList.add(complexButton);
            } else {
                throw new RuntimeException("unknown menu type: " + wxMenu.getType());
            }
        }
        if (buttonList.size() <= 0) {
            throw new RuntimeException("without wx menu");
        }
        return new Menu(buttonList.toArray(new Button[buttonList.size()]));
    }

    public boolean publishMsgMenu(String corpId, Integer agentId, String corpSecret) {
        Menu msgMenu = this.generateMsgMenu(corpId);
        return menuApi.createMenu(corpId, agentId, corpSecret, StringUtil.object2Json(msgMenu));
    }
}
